naming.ts ➔ classes   A
last analyzed

Complexity

Conditions 3

Size

Total Lines 39
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 28
dl 0
loc 39
c 0
b 0
f 0
rs 9.208
cc 3
1
import type {
2
  ClassHash,
3
} from "./main.types"
4
import type {
5
  CssModule,
6
  ActionsOf,
7
} from "./definitions.types"
8
import type { Falsy } from "./ts-swiss.types"
9
import {
10
  joinWithLead,
11
  resolver,
12
  wrapper
13
} from "./core"
14
import { EMPTY_OBJECT } from "./consts.json"
15
import type {
16
  ClassNamingFn,
17
  ClassNaming
18
} from "./naming.types"
19
20
export { classNaming }
21
22
/** Set context
23
 * @example
24
 * ```typescript
25
 *   const classes = classNaming({classnames: require("./some.css"), className?})
26
 *   const classes = classNaming(this.props)
27
 *   const classes = classNaming<Props>()
28
 *   const classes = classNaming<MyClassNames>()
29
 * ```
30
 */
31
function classNaming<
32
  Ctx extends {classnames: Source, className?: string},
33
  Source extends CssModule = Ctx["classnames"],
34
  WithClassName extends boolean = Ctx["className"] extends string ? true : false
35
>(
36
  context: Ctx = EMPTY_OBJECT as Ctx
37
): ClassNaming<WithClassName, {}, Source> {
38
  const {className} = context
39
40
  const host: ClassNamingFn<Source, {}, WithClassName> = (arg0?, arg1?) => classes(
41
    context,
42
    arg0,
43
    arg1
44
  )
45
46
  return wrapper(host, className)
47
}
48
49
/// CONTEXTED. TS-notation not matters
50
51
function classes<
52
  Source extends CssModule,
53
  Actions extends ActionsOf<Source>
54
>(
55
  {
56
    className,
57
    classnames,
58
    stacked: preStacked,
59
  }: {
60
    className?: string,
61
    classnames: Source,
62
    stacked?: string|undefined
63
  },
64
  arg0?: Falsy | true | Actions,
65
  arg1?: Falsy | Actions
66
): ClassNaming<boolean, {}, Source> {
67
  const source = typeof arg0 === "object" ? arg0 as Actions: arg1 as Actions
68
  //TODO check what will happen with classes()
69
  , allowed = source && resolver(classnames, source! /* TS-bug? `source` couldn't be `undefined`*/)
70
  , stacked = joinWithLead(preStacked, allowed)
71
  , result = arg0 === true && className
72
  ? joinWithLead(className, stacked)
73
  : stacked
74
  , host: ClassNamingFn<
75
    {[K in Exclude<keyof Source, keyof Actions>]: ClassHash},
76
    {},
77
    boolean
78
  > = (arg0?, arg1?) => classes({classnames, className, stacked: result},
79
    //@ts-expect-error Due to not accurate `withClassName`
80
    arg0,
81
    arg1
82
  )
83
84
  return wrapper(
85
    host,
86
    result,
87
  )
88
}
89